#pragma once
#include <iostream>
#include <functional>
#include <string>
#include <pthread.h>
#include <cassert>

class Thread;

//上下文
class Context
{
public:
    Thread* _this;
    void* _args;
public:
    Context()
        :_this(nullptr)
        ,_args(nullptr)
    {}
    ~Context(){}    
};



class Thread
{
public:
    typedef std::function<void*(void*)> func_t;
    const int num=1024;

    Thread(func_t func,void* args,int number);

    //使用静态方法
    static void* start_rountine(void* args)
    {
        //静态方法不能调用非静态成员，如果给成员加上static，就会导致
        //所有线程对象使用同一个函数，传递同一个参数
        //return _func(args);

        Context* con=static_cast<Context*>(args);
        void* ret=con->_this->run(con->_args);
        delete con;
        return ret;
    }

    // void start()
    // {
    //     Context* con=new Context();
    //     con->_this=this;
    //     con->_args=_args;

    //     //绕一大圈就是为了把_args传给_func
    //     int n=pthread_create(&_tid,nullptr,start_rountine,con);
    //     //int n=pthread_create(&_tid,nullptr,_func,con);C无法调用C++定义的包装器_func
    //     assert(n==0);
    //     (void)n;
    // }
    void join()
    {
       int n= pthread_join(_tid,nullptr);
       assert(n==0);
       (void)n;
    }
    void* run(void* args)
    {
        return _func(args);
    }

    ~Thread();
private:
   std::string _name;
   pthread_t _tid;
   func_t _func;
   void* _args;

};

Thread::Thread(func_t func,void* args,int number)
:_func(func),_args(args)
{
    char buffer[num];
    snprintf(buffer,sizeof buffer,"thread-%d",number);

    // _name="thread-";
    // _name+=std::to_string(number);

    Context* con=new Context();
    con->_this=this;
    con->_args=_args;

    //绕一大圈就是为了把_args传给_func
    int n=pthread_create(&_tid,nullptr,start_rountine,con);
    //int n=pthread_create(&_tid,nullptr,_func,con);C无法调用C++定义的包装器_func
    assert(n==0);
    (void)n;
}

Thread::~Thread()
{
}
